package com.sh.common.base;

import java.lang.reflect.ParameterizedType;
import java.util.List;

import javax.annotation.Resource;
import javax.persistence.Query;

import org.hibernate.Session;
import org.hibernate.SessionFactory;

/**
 * 
 * NOTE：基础dao
 *
 * @author： king
 * @date： 2019年3月31日
 *
 * @param <T>
 * @param <PK>
 */
public class BaseDao<T, PK> {

	@Resource
	private SessionFactory sessionFactory;
	
	private Class<T> clazz;
	
	@SuppressWarnings("unchecked")
	public BaseDao() {
		this.clazz = (Class<T>)((ParameterizedType)this.getClass().getGenericSuperclass())
                .getActualTypeArguments()[0];
	}

	/**
	 * 
	 * NOTE：获取session对象
	 *
	 * @author： king
	 * @date： 2019年3月31日
	 *
	 * @return
	 */
	protected Session getSession() {  
        return this.sessionFactory.getCurrentSession();  
    }  
	
	/**
	 * 
	 * NOTE：分页查询
	 *
	 * @author： king
	 * @date： 2019年3月31日
	 *
	 * @param sql
	 * @param params
	 * @param start
	 * @param rows
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public List<T> findByPage(String sql, List<Object> params, Integer start, Integer rows) {
		
		Query query = getSession().createNativeQuery(sql, this.clazz);
		if(params != null && params.size() > 0) {
			for(int i = 0; i < params.size(); i++) {
				
				query.setParameter(i+1, params.get(i));
			}
		}
		
		query.setFirstResult(start).setMaxResults(rows);
		
		return query.getResultList();
	}
	
	/**
	 * 
	 * NOTE：通过sql获取单独的一个结果
	 *
	 * @author： king
	 * @date： 2019年3月31日
	 *
	 * @param sql
	 * @param params
	 * @return
	 */
	public Object findSingleResult(String sql, List<Object> params) {
		
		Query query = getSession().createNativeQuery(sql);
		
		if(params != null && params.size() > 0) {
			for(int i = 0; i < params.size(); i++) {
				
				query.setParameter(i+1, params.get(i));
			}
		}
		
		return query.getSingleResult();
	}
	
	/**
	 * 
	 * NOTE：普通条件查询
	 *
	 * @author： king
	 * @date： 2019年3月31日
	 *
	 * @param sql
	 * @param params
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public List<T> find(String sql, List<Object> params){
		
		Query query = getSession().createNativeQuery(sql, this.clazz);
		
		if(params != null && params.size() > 0) {
			for(int i = 0; i < params.size(); i++) {
				
				query.setParameter(i+1, params.get(i));
			}
		}
		
		return query.getResultList();
	}
	
	/**
	 * 
	 * NOTE：通过id查询单个对象
	 *
	 * @author： king
	 * @date： 2019年3月31日
	 *
	 * @param sql
	 * @param id
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public T getById(String sql, PK id) {
		
		Query query = getSession().createNativeQuery(sql, this.clazz);
		query.setParameter(1, id);
		
		List<T> list = query.getResultList();
		
		if(list.isEmpty()) {
			
			return null;
		}
		
		return (T)list.get(0);
	}
	
	/**
	 * 
	 * NOTE：新增
	 *
	 * @author： king
	 * @date： 2019年3月31日
	 *
	 * @param t
	 */
	public void add(T t) {
		
		getSession().saveOrUpdate(t);
	}
	
	/**
	 * 
	 * NOTE：批量新增
	 *
	 * @author： king
	 * @date： 2019年3月31日
	 *
	 * @param list
	 */
	public void batchAdd(List<T> list) {
		
		getSession().saveOrUpdate(list);
	}
	
	/**
	 * 
	 * NOTE：修改
	 *
	 * @author： king
	 * @date： 2019年3月31日
	 *
	 * @param t
	 */
	public void update(T t) {
		
		getSession().update(t);
	}
	
	/**
	 * 
	 * NOTE：批量修改
	 *
	 * @author： king
	 * @date： 2019年3月31日
	 *
	 * @param list
	 */
	public void batchUpdate(List<T> list) {
		
		getSession().update(list);
	}
	
	/**
	 * 
	 * NOTE：删除
	 *
	 * @author： king
	 * @date： 2019年3月31日
	 *
	 * @param t
	 */
	public void detele(T t) {
		
		getSession().delete(t);
	}
	
	/**
	 * 
	 * NOTE：批量删除
	 *
	 * @author： king
	 * @date： 2019年3月31日
	 *
	 * @param list
	 */
	public void batchDelete(List<T> list) {
		
		getSession().delete(list);
	}
	
	/**
	 * 
	 * NOTE：执行sql
	 *
	 * @author： king
	 * @date： 2019年3月31日
	 *
	 * @param sql
	 * @param params
	 */
	public void executeBySql(String sql, List<Object> params) {
		
		Query query = getSession().createNativeQuery(sql);
		
		if(params != null && params.size() > 0) {
			for(int i = 0; i < params.size(); i++) {
				
				query.setParameter(i+1, params.get(i));
			}
		}
		
		query.executeUpdate();
	}
}
